#include "Me.h"
#include "ttClientPrxMgr.h"
#include "d3dDrawer.h"

Vertex::Vertex()
{}

Vertex::Vertex(float x,float y,float z):_x(x),_y(y),_z(z)  
{}

const D3DXMATRIX d3dDrawer::oneMatrix(1,0,0,0,
		0,1,0,0,
		0,0,1,0,
		0,0,0,1);

d3dDrawer::d3dDrawer() : m_d3d9(NULL), m_Device(NULL), m_VB(NULL), m_IB(NULL), m_brBegin(false)
{}

d3dDrawer::~d3dDrawer()
{
	if (NULL != m_d3d9){
		m_d3d9->Release();
	}
	if (NULL != m_Device){
		m_Device->Release();
	}
}

int 
d3dDrawer::init(HWND hwnd)
{
	m_d3d9 = Direct3DCreate9(D3D_SDK_VERSION);  
    if (NULL == m_d3d9){  
        MessageBox(NULL,L"create failed",L"failed",MB_OK);  
        return -1;  
    }  
    D3DCAPS9 caps;  
    m_d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT,  
        D3DDEVTYPE_HAL,  
        &caps);  
    int vp = 0;  
    if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT){  
        vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;  
    }  
    else{  
        vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;  
    }  
  
    D3DPRESENT_PARAMETERS d3dpp;  
    d3dpp.BackBufferWidth = 800;  
    d3dpp.BackBufferHeight = 600;  
    d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;  
    d3dpp.BackBufferCount = 1;  
    d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;  
    d3dpp.MultiSampleQuality = 0;  
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;  
    d3dpp.hDeviceWindow = hwnd;  
    d3dpp.Windowed = TRUE;  
    d3dpp.EnableAutoDepthStencil = TRUE;  
    d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;  
    d3dpp.Flags = 0;  
    d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;  
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;  
  
  
    if (FAILED(m_d3d9->CreateDevice(  
        D3DADAPTER_DEFAULT,  
        D3DDEVTYPE_HAL,  
        hwnd,  
        vp,  
        &d3dpp,  
        &m_Device))){  
            MessageBox(NULL,L"CreateDevice() Failed",L"failed",MB_OK);  
    }

	m_Device->CreateVertexBuffer(  
        12 * sizeof(Vertex),  
        D3DUSAGE_WRITEONLY,  
        Vertex::FVF,  
        D3DPOOL_MANAGED,  
        &m_VB,  
        0);  
  
    m_Device->CreateIndexBuffer(  
        42 * sizeof(WORD),  
        D3DUSAGE_WRITEONLY,  
        D3DFMT_INDEX16,  
        D3DPOOL_MANAGED,  
        &m_IB,  
        0);  
  
    Vertex* vertices = NULL;  
    m_VB->Lock(0, 0, (void**)&vertices, 0);  
  
    vertices[0] = Vertex(-1.0f,-1.0f,-1.0f);  
    vertices[1] = Vertex(-1.0f,1.0f,-1.0f);  
    vertices[2] = Vertex(1.0f,1.0f,-1.0f);  
    vertices[3] = Vertex(1.0f,-1.0f,-1.0f);  
    vertices[4] = Vertex(-1.0f,-1.0f,1.0f);  
    vertices[5] = Vertex(-1.0f,1.0f,1.0f);  
    vertices[6] = Vertex(1.0f,1.0f,1.0f);  
    vertices[7] = Vertex(1.0f,-1.0f,1.0f);  
	vertices[8] = Vertex(-50.0f,-2.0f,50.0f);
	vertices[9] = Vertex(50.0f,-2.0f,50.0f);
	vertices[10] = Vertex(50.0f,-2.0f,-50.0f);
	vertices[11] = Vertex(-50.0f,-2.0f,-50.0f);

	for (int i = 0; i < 8; ++ i){
		vertices[i]._color = D3DCOLOR_XRGB(123,123,123);
	}
	vertices[8]._color = D3DCOLOR_XRGB(255, 0, 0);
	vertices[9]._color = D3DCOLOR_XRGB(0, 255, 0);
	vertices[10]._color = D3DCOLOR_XRGB(0, 0, 255);
	vertices[11]._color = D3DCOLOR_XRGB(255, 0, 0);
  
    m_VB->Unlock();  
  
    WORD* indices = NULL;  
  
    m_IB->Lock(0, 0, (void**)&indices, 0);  
  
    indices[0] = 0;indices[1] = 1;indices[2] = 2;  
    indices[3] = 0;indices[4] = 2;indices[5] = 3;  
  
    indices[6] = 4;indices[7] = 6;indices[8] = 5;  
    indices[9] = 4;indices[10] = 7;indices[11] = 6;  
  
    indices[12] = 4;indices[13] = 5;indices[14] = 1;  
    indices[15] = 4;indices[16] = 1;indices[17] = 0;  
  
    indices[18] = 3;indices[19] = 2;indices[20] = 6;  
    indices[21] = 3;indices[22] = 6;indices[23] = 7;  
  
    indices[24] = 1;indices[25] = 5;indices[26] = 6;  
    indices[27] = 1;indices[28] = 6;indices[29] = 2;  
  
    indices[30] = 4;indices[31] = 0;indices[32] = 3;  
    indices[33] = 4;indices[34] = 3;indices[35] = 7; 

	indices[36] = 8;indices[37] = 9;indices[38] = 11;  
	indices[39] = 9;indices[40] = 10;indices[41] = 11;  
  
    m_IB->Unlock();  
  
	D3DXVECTOR3 position(0.0f, 10.0f, -10.0f);  
    D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);  
    D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);  
    D3DXMATRIX V;  
    D3DXMatrixLookAtLH(&V, &position, &target, &up);  
    m_Device->SetTransform(D3DTS_VIEW, &V);  
    D3DXMATRIX proj;  
    D3DXMatrixPerspectiveFovLH(  
        &proj,  
        D3DX_PI * 0.5f,  
        (float)4 / (float)3,  
        1.0f,  
        1000.0f);  
    m_Device->SetTransform(D3DTS_PROJECTION,&proj);  
	m_Device->SetRenderState(D3DRS_LIGHTING, false);
    m_Device->SetRenderState(D3DRS_SHADEMODE,D3DSHADE_GOURAUD);  
	return 0;
}

int
d3dDrawer::begin()
{
	m_brBegin = true;
	return 0;
}

int
d3dDrawer::render(float timeDelta)
{
	if (m_brBegin){
		if (m_Device){  

			D3DXVECTOR3 position(Me->getX() - 10*sin(Me->getDirection()), 20.0f, Me->getY() - 10*cos(Me->getDirection()));  
			D3DXVECTOR3 target(Me->getX(), 0, Me->getY());  
			D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);  
			D3DXMATRIX V;  
			D3DXMatrixLookAtLH(&V, &position, &target, &up);  
			m_Device->SetTransform(D3DTS_VIEW, &V);  


			m_Device->Clear(0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,  
				0xffffffff, 1.0f, 0);  
			m_Device->BeginScene();  

			for (ttClientPrxMgr::THISLIST::iterator iter = ttClientPrxMgr::Get()->getList().begin(); iter != ttClientPrxMgr::Get()->getList().end(); ++ iter){
				(*iter)->draw(m_Device, timeDelta);
			}

			Me->draw(m_Device, timeDelta);

			static float y = 0.0f,x = 0.0f;  
			D3DXMATRIX Rx,Ry;  
			D3DXMatrixRotationX(&Rx, x);  
			D3DXMatrixRotationY(&Ry, y);   
			x += 2 * timeDelta;  
			y += timeDelta;  
			if (x >= 6.28f) x = 0.0f;  
			if (y >= 6.28f) y = 0.0f;  
			D3DXMATRIX p = Rx * Ry;  
			m_Device->SetTransform(D3DTS_WORLD,&p); 
			m_Device->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
			m_Device->SetStreamSource(0, m_VB, 0, sizeof(Vertex));  
			m_Device->SetIndices(m_IB);  
			m_Device->SetFVF(Vertex::FVF);  
			m_Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);

			m_Device->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
			m_Device->SetTransform(D3DTS_WORLD,&oneMatrix);
			m_Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 8, 0, 4, 0, 2);

			m_Device->EndScene();  
			m_Device->Present(0, 0, 0, 0);  
		} 
	}
	return 0;
}

IDirect3DDevice9*
d3dDrawer::getDevice()
{
	return m_Device;
}